#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.utils;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import ${package}.exceptions.BusinessException;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.Map;

import static ${package}.enums.ErrorCodeEnum.SPEL_EVAL_EXCEPTION;


/**
 * @version: 1.00.00
 * @description:
 * @copyright: Copyright (c) 2023 立林科技 All Rights Reserved
 * @company: 厦门立林科技有限公司
 * @date: 2023-10-21 16:32
 */
@Slf4j
public class SpelUtils {

    /**
     * spel表达式
     * @param expr
     * @param factsMap
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T parse(String expr, Map<String, Object> factsMap, Class<T> tClass) {
        log.info("expr={}, factsMap={}", expr, JSON.toJSONString(factsMap));
        ExpressionParser expressionParser = new SpelExpressionParser();
        //创建上下文变量
        StandardEvaluationContext ctx = new StandardEvaluationContext();
        ctx.setVariables(factsMap);
        Expression expression = expressionParser.parseExpression(expr);
        return expression.getValue(ctx, tClass);
    }

    /**
     * 校验spel表达式
     * @param expr
     */
    public static void validate(String expr, Map<String, Object> factsMap, boolean isCon){
        try {
            ExpressionParser expressionParser = new SpelExpressionParser();
            //创建上下文变量
            StandardEvaluationContext ctx = new StandardEvaluationContext();
            ctx.setVariables(factsMap);
            Expression expression = expressionParser.parseExpression(expr);
            if(isCon){
                expression.getValue(ctx, Boolean.class);
                return;
            }
            expression.getValue(ctx);
        } catch (Exception e) {
            log.error("spel表达式校验失败,params={}", expr);
            throw new BusinessException(SPEL_EVAL_EXCEPTION, e, expr);
        }
    }
    public static void main(String[] args) {
        String expr = "${symbol_pound}field=${symbol_pound}amount";
        Map<String, Object> factsMap = Maps.newHashMap();
        factsMap.put("amount", 0);
        factsMap.put("field", 0);
        validate(expr, factsMap,true);
//        Seq.TreeNode root = new Seq.TreeNode();
//        root.setId("1").setParentId("0");
//        Seq.TreeNode root1 = new Seq.TreeNode();
//        root1.setId("2").setParentId("0");
//        Seq.TreeNode child = new Seq.TreeNode();
//        child.setId("3").setParentId("1");
//        Seq.TreeNode child1 = new Seq.TreeNode();
//        child1.setId("4").setParentId("2");
//        Seq.TreeNode child2 = new Seq.TreeNode();
//        child2.setId("5").setParentId("1");
//        Seq.TreeNode child21 = new Seq.TreeNode();
//        child21.setId("6").setParentId("2");
//        Seq.TreeNode child3 = new Seq.TreeNode();
//        child3.setId("7").setParentId("5");
//        Seq.TreeNode child31 = new Seq.TreeNode();
//        child31.setId("8").setParentId("6");
//        List<Seq.TreeNode> nodeList = Lists.newArrayList(root1, root, child, child1, child2, child21, child3, child31);
//        Seq.genTree(nodeList, Seq.TreeNode::getId, Seq.TreeNode::getParentId, node -> "0".equals(node.getParentId()),  Seq.TreeNode :: setChildren)
//                .forEachTree(node -> Seq.of(node.getChildren()))
//                .foreach(node -> log.info("node={}", JSON.toJSONString(node)));
    }
}
